package org.example.util;

import com.univocity.parsers.common.processor.RowListProcessor;
import com.univocity.parsers.csv.CsvFormat;
import com.univocity.parsers.csv.CsvParser;
import com.univocity.parsers.csv.CsvParserSettings;
import com.univocity.parsers.csv.CsvWriter;
import com.univocity.parsers.csv.CsvWriterSettings;
import org.example.csv.CSVData;
import org.example.csv.OutCSVData;
import org.example.model.LongStringResult;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CSVFaster {

    public static CSVData read(Path p) {
        // 创建一个配置选项，用来提供多种配置选项
        CsvParserSettings parserSettings = new CsvParserSettings();
        parserSettings.setDelimiterDetectionEnabled(true);
        // 打开解析器的自动检测功能，让它自动检测输入中包含的分隔符
        parserSettings.setLineSeparatorDetectionEnabled(true);

        // 创建 RowListProcessor 对象，用来把每个解析的行存储在列表中
        RowListProcessor rowListProcessor = new RowListProcessor();
        parserSettings.setProcessor(rowListProcessor);  //配置解析器
        // 待解析的 CSV 文件包含标题头，把第一个解析行看作文件中每个列的标题
        parserSettings.setHeaderExtractionEnabled(true);

        // 创建 CsvParser 对象，用于解析文件
        CsvParser parser = new CsvParser(parserSettings);
        parser.parse(p.toFile());

        // 如果解析中包含标题，用于获取标题
        String[] headers = rowListProcessor.getHeaders();
        CSVData csvData = new CSVData(Arrays.asList(headers));
        // 获取行值，并遍历打印
        List<String[]> rows = rowListProcessor.getRows();
        csvData.setLines(rows);
        /*for(int i = 0; i < rows.size(); i++){
            System.out.println(Arrays.asList(rows.get(i)));
        }*/
        return csvData;
    }

    public static CSVData read(Path p, List<String> selectedHeaders) {
        CSVData csvData;
        // 创建一个配置选项，用来提供多种配置选项
        CsvParserSettings parserSettings = new CsvParserSettings();
        parserSettings.setDelimiterDetectionEnabled(true);
        // 打开解析器的自动检测功能，让它自动检测输入中包含的分隔符
        parserSettings.setLineSeparatorDetectionEnabled(true);
        parserSettings.selectFields(selectedHeaders.toArray(new String[0]));

        // 创建 RowListProcessor 对象，用来把每个解析的行存储在列表中
        RowListProcessor rowListProcessor = new RowListProcessor();
        parserSettings.setProcessor(rowListProcessor);  //配置解析器
        // 待解析的 CSV 文件包含标题头，把第一个解析行看作文件中每个列的标题
        parserSettings.setHeaderExtractionEnabled(true);

        // 创建 CsvParser 对象，用于解析文件
        CsvParser parser = new CsvParser(parserSettings);
        parser.parse(p.toFile());

        // 如果解析中包含标题，用于获取标题
        // String[] headers = rowListProcessor.getHeaders();
        csvData = new CSVData(selectedHeaders);
        //获取行值，并遍历打印
        List<String[]> rows = rowListProcessor.getRows();
        csvData.setLines(rows);
        /*for(int i = 0; i < rows.size(); i++){
            System.out.println(Arrays.asList(rows.get(i)));
        }*/
        return csvData;
    }

    public static void write(Path p, CSVData csvData) {
        File file = p.toFile();
        try {
            Writer fileWriter = new BufferedWriter(new FileWriter(file));
            CsvWriterSettings settings = new CsvWriterSettings();
            CsvFormat format = settings.getFormat();
            format.setDelimiter("|");
            CsvWriter writer = new CsvWriter(fileWriter, settings);
            writer.writeHeaders(csvData.getHeaders());
            writer.writeRowsAndClose(new ArrayList<>(csvData.getLines()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void write(Path p, OutCSVData outCSVData) {
        try {
            Writer fileWriter = new FileWriter(p.toFile());
            CsvWriterSettings settings = new CsvWriterSettings();
            CsvWriter writer = new CsvWriter(fileWriter, settings);
            List<LongStringResult> outLines = outCSVData.getOutLines();
            writer.writeRow("id|value");
            for (LongStringResult line : outLines) {
                writer.writeRow(line.toString());
            }
            writer.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void writeV1(Path p, OutCSVData outCSVData) {
        try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(p.toFile()))) {
            List<LongStringResult> outLines = outCSVData.getOutLines();
            StringBuilder res = new StringBuilder("id|value\n");
            for (LongStringResult line : outLines) {
                res.append(line);
            }
            bufferedWriter.write(res.toString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
